#include <stdlib.h>
#include "RGB.h"


void RGBInit(void)
{
    Color_t color = {0, 0, 0};
    for (uint8_t i = 0; i < LED_NUMBER; i++)
        SetRgbBufferByID(i, color, 0);
    SyncLights();
}

uint8_t getIdByMatrix(uint8_t x, uint8_t y)
{
    if ((x & 1) == 0) { // 等价于 x % 2 == 0
        return y + (x << 3); // 等价于 y + x * 8
    }
    return ((x + 1) << 3) - y - 1; // 等价于 (x + 1) * 8 - y - 1
}

void SetRgbBufferByID(uint8_t _keyId, Color_t _color, float _brightness)
{
    // To ensure there's no sequence zero bits, otherwise will case ws2812b protocol error.
    if (_color.b < 1)_color.b = 1;

    for (int i = 0; i < 8; i++)
    {
        rgbBuffer[_keyId][0][i] =
                ((uint8_t) ((float) _color.g * _brightness) >> brightnessPreDiv) & (0x80 >> i) ? HIGH : LOW;
        rgbBuffer[_keyId][1][i] =
                ((uint8_t) ((float) _color.r * _brightness) >> brightnessPreDiv) & (0x80 >> i) ? HIGH : LOW;
        rgbBuffer[_keyId][2][i] =
                ((uint8_t) ((float) _color.b * _brightness) >> brightnessPreDiv) & (0x80 >> i) ? HIGH : LOW;
    }
}

void setIsRgbTxBusy(bool isBusy)
{
    isRgbTxBusy = isBusy;
}


void SyncLights()
{
    while (isRgbTxBusy);
    isRgbTxBusy = true;
    HAL_SPI_Transmit_DMA(&hspi1, (uint8_t*) rgbBuffer, LED_NUMBER * 3 * 8);
}

Color_t ColorRand(uint8_t seed)
{
    srand(seed);
    uint8_t r = rand() % 250;
    uint8_t g = rand() % 250;
    uint8_t b = rand() % 250;
    return (Color_t){r, g, b};
}

/**------------------------- RGB effect -----------------------------------------*/
void breatheEffect(Color_t color)
{
    for (int i = rhythmDiv; i < LED_NUMBER; ++i) {
        SetRgbBufferByID(i, color, brightness);
    }
    SyncLights();
    if (brightness >= MAX_BREATH_LIGHT) breathe = false;
    if (brightness <= MIN_BREATH_LIGHT) breathe = true;
    breathe ? (brightness += breatheDiv) : (brightness -= breatheDiv);
}
void rhythmEffect()
{
    for (int i = 0; i < rhythmDiv; ++i) {
        SetRgbBufferByID(i, RAINBOW_Color[i/13], MAX_BREATH_LIGHT);
    }
    for (int i = rhythmDiv; i < LED_NUMBER; ++i) {
        SetRgbBufferByID(i, (Color_t){0,0,0},0);
    }
    SyncLights();
    if (rhythmDiv >= LED_NUMBER) rhythm = false;
    if (rhythmDiv <= 0) rhythm = true;
    rhythm ? rhythmDiv++ : rhythmDiv--;
}
void simpleRhythmEffect(uint8_t div)
{
    for (int i = 0; i < div; ++i) {
        SetRgbBufferByID(i, RAINBOW_Color[i%13], MAX_BREATH_LIGHT);
    }
    for (int i = div; i < LED_NUMBER; ++i) {
        SetRgbBufferByID(i, (Color_t){0,0,0},0);
    }
    SyncLights();
    if (div >= LED_NUMBER) rhythm = false;
    if (div <= 0) rhythm = true;
    rhythm ? div++ : div--;
}
void musicRhythmEffect(uint8_t power, Color_t color)
{
    for (int i = 0; i < power; ++i) {
        SetRgbBufferByID(i, color, MAX_BREATH_LIGHT);
    }
    for (int i = power; i < LED_NUMBER; ++i) {
        SetRgbBufferByID(i, (Color_t){0,0,0},0);
    }
    SyncLights();
}
void rainbowEffect()
{
    for (int i = 0; i < LED_NUMBER; ++i) {
        SetRgbBufferByID(i, RAINBOW_Color[i%13], 1);
    }
    SyncLights();
}

/**------------------------------------------------------------------------------*/



